package li.kaeppe.travel.tracker.web.backing;

import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;

import li.kaeppe.travel.tracker.domain.User;
import li.kaeppe.travel.tracker.domain.UserRole;
import li.kaeppe.travel.tracker.service.UserService;
import li.kaeppe.travel.tracker.web.bean.PasswordChangeBean;

public class UserBackingBean {

	/* **************************************************** */
	/*                      CONSTANTS                       */
	/* **************************************************** */

	/* **************************************************** */
	/*                     MEMBER FIELDS                    */
	/* **************************************************** */

	private UserService userService;
	
	private User user;
	
	private PasswordChangeBean password;
	
	private Long[] roles;
	
	private SelectItem[] allRoles;
	
	private DataModel userModel = new ListDataModel();
	
	/* **************************************************** */
	/*                      CONSTRUCTOR                     */
	/* **************************************************** */

	/* **************************************************** */
	/*                    PUBLIC METHODS                    */
	/* **************************************************** */

	public DataModel getAllUsers() {
		List<User>users = this.getUserService().getAllUsers();
		this.userModel.setWrappedData(users);
		
		return this.userModel;
	}
	
	public String createUser() {
		this.user = new User();
		this.password = new PasswordChangeBean(true);
		
		this.initRoles();
		
		return "create";
	}
	
	public String editUser() {
		this.user = (User)userModel.getRowData();
		this.password = new PasswordChangeBean(false);
		
		this.initRoles();
		this.initCurrentRoles(user.getAuthorities());
		
		return "edit";
	}
	
	public String saveUser() {
		
		if(this.getPassword().isPasswordSet()) {
			if(this.getPassword().isPasswordValid()) {
				this.getUser().setPassword(this.getPassword().getPassword());
			} else {
				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
				         "Password Mismatch", "The given password doesn't match."));
				return "error";
			}
		}
		
		UserRole[] selectedRoles = new UserRole[roles.length];
		for(int i = 0; i < roles.length; i++) {
			selectedRoles[i] = this.getUserService().getRoleById(roles[i]);
		}
		
		user.setAuthorities(selectedRoles);
		
		this.getUserService().saveUser(user);
		
		this.reset();
		return "save";
	}
	
	public String cancelUser() {
		this.reset();
		return "cancel";
	}
	
	public String deleteUser() {
		this.user = (User)userModel.getRowData();
		
		this.getUserService().deleteUser(user);
		
		return "deleted";
	}
	
	/* **************************************************** */
	/*                  PROTECTED METHODS                   */
	/* **************************************************** */

	/* **************************************************** */
	/*                   PRIVATE METHODS                    */
	/* **************************************************** */

	private void reset() {
		this.user = null;
		this.getPassword().setPassword("");
		this.getPassword().setPasswordConfirmation("");
	}
	
	private void initRoles() {
		List<UserRole> allUserRoles = this.getUserService().getAllRoles();
		allRoles = new SelectItem[allUserRoles.size()];
		int i = 0;
		for(UserRole role: allUserRoles) {
			allRoles[i++] = new SelectItem(role.getId(), role.getDescription());
		}
		
		this.roles = new Long[0];
	}
	
	private void initCurrentRoles(UserRole[] userRoles) {
		Long[] roleIds = new Long[userRoles.length];
		
		for(int i = 0; i < userRoles.length; i++) {
			roleIds[i] = userRoles[i].getId();
		}
		
		roles = roleIds;
	}
	
	/* **************************************************** */
	/*                  GETTERS AND SETTERS                 */
	/* **************************************************** */
	
	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public DataModel getUserModel() {
		return userModel;
	}

	public void setUserModel(DataModel userModel) {
		this.userModel = userModel;
	}

	public PasswordChangeBean getPassword() {
		return password;
	}

	public void setPassword(PasswordChangeBean password) {
		this.password = password;
	}

	public Long[] getRoles() {
		return roles;
	}

	public void setRoles(Long[] roles) {
		this.roles = roles;
	}

	public SelectItem[] getAllRoles() {
		return allRoles;
	}

	public void setAllRoles(SelectItem[] allRoles) {
		this.allRoles = allRoles;
	}
	
}
